import { useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
import AMapLoader from '@amap/amap-jsapi-loader';
import styles from './index.less';

export type MapStyle =
    | 'amap://styles/normal' //标准
    | 'amap://styles/dark' //幻音黑
    | 'amap://styles/light' //月光银
    | 'amap://styles/whitesmoke' //远山黛
    | 'amap://styles/fresh' //草色青
    | 'amap://styles/grey' //雅士灰
    | 'amap://styles/graffiti' //涂鸦
    | 'amap://styles/macaron' //马卡龙
    | 'amap://styles/blue' //靛青蓝
    | 'amap://styles/darkblue' //极夜蓝
    | 'amap://styles/wine'; //酱紫

type Props = {
    initialPosition?: number[];
    viewMode?: '2D' | '3D';
    zoom?: number;
    height?: number | string;
    mapStyle?: MapStyle;
    zooms?: number[];

    // 事件
    onLoadComplete?: () => void;
    onMoveStart?: () => void;
    onMove?: (event: any) => void;
    onMoveEnd?: () => void;
    onZoomStart?: () => void;
    onZoom?: (event: any) => void;
    onZoomEnd?: () => void;
    onDragStart?: () => void;
    onDrag?: (event: any) => void;
    onDragEnd?: () => void;
};

export interface AMapRef {
    getZoom: () => number;
    setZoom: (_zoom: number) => void;
    getCenter: () => number;
    setCenter: (_center: number[]) => void;
    getCurrentCity: (_callback: (info: any) => void) => void;
    setCurrentCity: (_city: any) => void;
    getBounds: () => any;
    setBounds: (bounds: any) => void;
    getLimitBounds: () => any;
    setLimitBounds: (_p1: number[], _p2: number[]) => void;
    addMarker: (_marker: any | any[]) => void;
    removeMarker: (_marker: any | any[]) => void;
    addPolyline: (_polyline: any | any[]) => void;
    removePolyline: (_polyline: any | any[]) => void;
}

export default forwardRef((props: Props, ref) => {
    const {
        initialPosition,
        viewMode,
        height,
        mapStyle,
        zoom,
        zooms,
        onLoadComplete,
        onMoveStart,
        onMove,
        onMoveEnd,
        onZoomStart,
        onZoom,
        onZoomEnd,
        onDragStart,
        onDrag,
        onDragEnd,
    } = props;

    const mapRef = useRef<any>();

    const getZoom = (): number => {
        return mapRef.current?.getZoom();
    };

    const setZoom = (_zoom: number) => {
        mapRef.current?.setZoom(_zoom);
    };

    const getCenter = (): number => {
        return mapRef.current?.getCenter();
    };

    const setCenter = (_center: number[]) => {
        mapRef.current?.setCenter(_center);
    };

    const getCurrentCity = (_callback: (info: any) => void) => {
        return mapRef.current?.getCity(_callback);
    };

    const setCurrentCity = (_city: any) => {
        mapRef.current?.setCity(_city);
    };

    const getBounds = (): any => {
        return mapRef.current?.getBounds();
    };

    const setBounds = (bounds: any) => {
        // const bounds = [..._p1, ..._p2];
        mapRef.current?.setBounds(bounds);
    };

    const getLimitBounds = (): any => {
        return mapRef.current?.getLimitBounds();
    };

    const setLimitBounds = (_p1: number[], _p2: number[]) => {
        const bounds = [..._p1, ..._p2];
        mapRef.current?.setLimitBounds(bounds);
    };

    const addMarker = (_marker: any) => {
        mapRef.current?.add(_marker);
    };

    const removeMarker = (_marker: any) => {
        mapRef.current?.remove(_marker);
    };

    const addPolyline = (_polyline: any) => {
        mapRef.current?.add(_polyline);
    }

    const removePolyline = (_polyline: any) => {
        mapRef.current?.remove(_polyline);
    }

    useImperativeHandle(ref, () => {
        return {
            getZoom,
            setZoom,
            getCenter,
            setCenter,
            getCurrentCity,
            setCurrentCity,
            getBounds,
            setBounds,
            getLimitBounds,
            setLimitBounds,
            addMarker,
            removeMarker,
            addPolyline,
            removePolyline,
        };
    });

    useEffect(() => {
        // @ts-ignore
        window._AMapSecurityConfig = {
            securityJsCode: 'baedf4408cc8f2313c318a596fd6922e',
        };
        AMapLoader.load({
            key: '576f2bda906f938fb846b4b919d54134', // 申请好的Web端开发者Key，首次调用 load 时必填
            version: '2.0', // 指定要加载的 JSAPI 的版本，缺省时默认为 1.4.15
            plugins: ['AMap.Scale'], // 需要使用的的插件列表，如比例尺'AMap.Scale'，支持添加多个如：['...','...']
        })
            .then((AMap) => {
                const map = new AMap.Map('container', {
                    viewMode: viewMode || '3D', // 是否为3D地图模式
                    zoom: zoom || 11, // 初始化地图级别
                    zooms: zooms || [3, 18], //缩放级别范围
                    center:
                        initialPosition && initialPosition?.length >= 2
                            ? initialPosition
                            : [116.397428, 39.90923], // 初始化地图中心点位置
                    mapStyle: mapStyle || 'amap://styles/normal', // 地图样式
                    showIndoorMap: true,
                    dragEnable: true,
                    keyboardEnable: false,
                    zoomEnable: true,
                    doubleClickZoom: true,
                    rotateEnable: true,
                });

                map.setDefaultCursor('pointer');

                map.on('complete', onLoadComplete);
                map.on('movestart', onMoveStart);
                map.on('mapmove', onMove);
                map.on('moveend', onMoveEnd);
                map.on('zoomstart', onZoomStart);
                map.on('zoomchange', onZoom);
                map.on('zoomend', onZoomEnd);
                map.on('dragstart', onDragStart);
                map.on('dragging', onDrag);
                map.on('dragend', onDragEnd);

                mapRef.current = map;
            })
            .catch((e) => {
                console.log(e);
            });

        return () => {
            mapRef.current?.off('complete', onLoadComplete);
            mapRef.current?.off('movestart', onMoveStart);
            mapRef.current?.off('mapmove', onMove);
            mapRef.current?.off('moveend', onMoveEnd);
            mapRef.current?.off('zoomstart', onZoomStart);
            mapRef.current?.off('zoomchange', onZoom);
            mapRef.current?.off('zoomend', onZoomEnd);
            mapRef.current?.off('dragstart', onDragStart);
            mapRef.current?.off('dragging', onDrag);
            mapRef.current?.off('dragend', onDragEnd);

            mapRef.current?.destroy();
        };
    }, []);

    return (
        <div
            id='container'
            className={styles.container}
            style={{ height: height ? (typeof height === 'string' ? height : `${height}px`) : '450px' }}
        />
    );
});
